`timescale 1ns / 1ps
/////////////////////////////////////////////////////////////////////////////
////                                                                     ////
//// Instituto Tecnologico de Costa Rica                                 ////
////                                                                     ////
//// Maquina estados finitos principal                                   ////
////                                                                     ////
//// Este archivo es parte del proyecto: Pong Game                       ////
//// http://repositorio-charmander.googlecode.com/svn/trunk/             ////
////                                                                     ////
//// Descripcion                                                         ////
//// Implementacion de un control de luces de semaforo como un proyecto  ////
//// del curso de Taller de Dise;o Digital.                              ////
////                                                                     ////
//// Funcionamiento:                                                     ////
//// - Maquina de estados del juego de Pong. En este modulo es           ////
////   donde se procesan y se da la toma de decisiones por parte del     ////
////   programa para saber a que estado debera pasar segun las valores   ////
////   que ingresen.                                                     ////
////                                                                     ////
////                                                                     ////                                    
//// Autores:                                                            ////
//// - Gia Chen, kathya0812@gmail.com                                    ////
////   Edgar Rojas, edtec217@gmail.com                                   ////
////                                                                     ////
/////////////////////////////////////////////////////////////////////////////
module major_FSM(_clk_i,_sync_rst_i,_sync_up_i,_sync_down_i,inicia_i,pierde_i,posicion_paleta_o,
						inicia_fsm_minor_o,fin_juego_o);

	//Inputs
	input _clk_i;
	input _sync_rst_i;
	input _sync_up_i;
	input _sync_down_i;
	input inicia_i;
	input pierde_i;
	
	//Outputs
	output reg [9:0] posicion_paleta_o;
	output reg inicia_fsm_minor_o;
	output reg fin_juego_o;
	
	
	//Variables Temporales
	reg [2:0] estado_actual;
	reg [19:0] contador_paleta;

	always @(posedge _clk_i)
	begin
		//Condicion que me indica si se hace un reset, en el caso de que 
		//se de un reset se vuelvo al estado 0.
		if (_sync_rst_i) 
			begin
				estado_actual <= 0;
			end
		else begin
			case (estado_actual)
				//Estado 0: se inicializan las variables de salida.
				3'b000:  
					begin
						posicion_paleta_o <= 0;
						inicia_fsm_minor_o <=  0;
						fin_juego_o <= 0;
						estado_actual <= 1;
					end
				//Estado 1: Posicion inicial de la paleta y espera la se;al de inicia_i la cual inicia el juego.
				3'b001:  
					begin
						posicion_paleta_o <= 10'b0011100001;
						inicia_fsm_minor_o <=  0;
						fin_juego_o <= 0;
						if (inicia_i)
							begin
								estado_actual <= 2; 
							end
						else  
							begin 
								estado_actual <= 1;
							end                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
					end
				//Estado 2: Se inicia la maquina de estados finitos menor.
				3'b010: 
					begin
						posicion_paleta_o <= 10'b0011100001;
						inicia_fsm_minor_o <=  1;
						fin_juego_o <= 0;
						estado_actual <= 3;
					end
				//Se controla la paleta en el juego segun las se;ales de  entrada up or down.
				3'b011:  
					begin
						if (_sync_up_i || _sync_down_i)
						begin
							if (contador_paleta == 390625) //Frecuencia
							begin
								contador_paleta <= 0;
								if (_sync_up_i)begin
									if (posicion_paleta_o > 10'b0000001000)
										begin
											 posicion_paleta_o <= posicion_paleta_o - 1;
										end
									else 
										begin
											 posicion_paleta_o <= posicion_paleta_o;
										end
								end
								else begin
									if (posicion_paleta_o < 10'b0110010111) begin
										posicion_paleta_o <= posicion_paleta_o + 1;
									end
									else begin
										 posicion_paleta_o <= posicion_paleta_o;
									end
								end
							end
							else begin contador_paleta <= contador_paleta + 1; end 
						end
						else begin contador_paleta <= 0; end
						inicia_fsm_minor_o <=  0;
						fin_juego_o <= 0;
						if (pierde_i) begin estado_actual <= 4; end
						else begin estado_actual <= 3; end  
					end
				//Estado 4: Fin del juego, este estado se encarga de detener el juego. 
				//Y espera a que el usuario reinicie el juego.
				3'b100:
					begin
						posicion_paleta_o <= posicion_paleta_o;
						inicia_fsm_minor_o <=  0;
						fin_juego_o <= 1;
						if (_sync_rst_i == 0) begin estado_actual <= 4;	end
						else begin estado_actual <= 1; end  
					end
			endcase
		end
	end
					
endmodule

